前一天我們學到 jq filter 可以經過判斷之後篩選出想要的資料,今天來看看 jq filter 如何讓結果轉換成我們想要的物件或陣列。
師傅:我們要來學習如何用 jq 建立新的 JSON 物件和陣列。準備好了嗎?
徒弟:是的,師傅!我已經迫不及待要學習新的技能了。
師傅:很好。首先,我們來看看如何建立一個新的 JSON 物件。試試這個命令:jq "{newObject: .}" todos.json
徒弟:哇!這是把整個 todos.json 的內容放到一個叫 newObject 的屬性裡了嗎?
師傅:沒錯。現在,讓我們試試建立一個新的陣列。執行這個:jq "[.[] | {id: .id, title: .title}]" todos.json
徒弟:這...這是建立了一個只有 id 和 title 屬性物件的新陣列?
師傅:正確。現在,讓我介紹一下 map 函數。map 會對陣列中的每個元素應用相同的轉換。試試這個:jq "map({id: .id, title: .title})" todos.json
徒弟:哦,這看起來跟剛才的結果一樣,但寫法更簡潔了!
師傅:沒錯。map 和直接使用 [] 的主要區別在於可讀性和複雜度。對於簡單的轉換,map 通常更清晰。但對於更複雜的操作,有時直接使用 [] 會更靈活。
徒弟:我明白了。那麼,我們應該在什麼時候選擇使用 map,什麼時候選擇使用 []?
師傅:好問題。一般來說,當你要對陣列中的每個元素進行相同的簡單轉換時,使用 map。如果你需要更複雜的邏輯或條件判斷,使用 [] 可能更合適。繼續練習,你會逐漸掌握使用的時機。
徒弟:謝謝師傅!我會努力練習的!
{}
建立新物件;使用 []
建立新陣列先前學過使用 .
取得輸入的 JSON、 .{屬性}
取得 JSON 物件的屬性值、.[]
取得 JSON 陣列的元素。當我們想要轉換成需要的 JSON 格式時,可以透過 {}
或 []
括住我們要取得的內容,來建立新的物件或陣列。
例如,原本的 TODO :
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
若只想看 id 和 title ,要組成 {"id": 1, "title": "delectus aut autem"}
這樣只有兩個屬性的物件,可以透過 {}
括住我們要取得的內容 id: .id , title: .title
,也就是 {id: .id , title: .title}
建立新的物件。
值得一提的是 {id: .id , title: .title}
這個物件,因為他的新屬性 id
與原屬性 .id
名稱相同、新屬性 title
與原屬性 .title
名稱相同,因此有便捷的寫法:
{id, title}
jq ". | {id, title}" todo.json
jq "[.[] | {id, title}]" todos.json
上面兩個例子,互相對照之下,會更清楚{}
和[]
個別的使用時機。注意便捷的寫法只有名稱相同時才能使用,要改屬性名稱的話,當然要指定新屬性名稱囉!
map(filter表達式) ,這個 map 的作用,就是將自己前面接收到的的輸入值,執行 [.[] | filter表達式]
。例如對話中的 jq "[.[] | {id, title}]" todos.json
與 jq "map({id: .id, title: .title})" todos.json
有相同的結果,參考下圖使用 jqplay 執行兩者比較的結果。
今天學到了利用表達式{}
和[]
,將輸入的資料轉換成自己想要的形式。也學到了 map
函式
的作用。我個人覺得 map 不是那麼直覺,因為我直覺想到的 map 也是 key:value 形式的那一種。不過一回生二回熟,之後若是有用到的時候,也能回頭查看這個 map 的定義啦! 感謝總是努力的自己~:)